/*
	角色动作信息
*/

package net.sf.odinms.net.channel.handler;

import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

import net.sf.odinms.net.AbstractMaplePacketHandler;
import net.sf.odinms.server.maps.AnimatedMapleMapObject;
import net.sf.odinms.server.movement.AbsoluteLifeMovement;
import net.sf.odinms.server.movement.ArasMovement;
import net.sf.odinms.server.movement.ChairMovement;
import net.sf.odinms.server.movement.ChangeEquipSpecialAwesome;
import net.sf.odinms.server.movement.JumpDownMovement;
import net.sf.odinms.server.movement.LifeMovement;
import net.sf.odinms.server.movement.LifeMovementFragment;
import net.sf.odinms.server.movement.RelativeLifeMovement;
import net.sf.odinms.server.movement.TeleportMovement;
import net.sf.odinms.tools.HexTool;
import net.sf.odinms.tools.WriteToFile;
import net.sf.odinms.tools.data.input.LittleEndianAccessor;

public abstract class AbstractMovementPacketHandler extends AbstractMaplePacketHandler {

    private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(AbstractMovementPacketHandler.class);
 
    //角色移动
    protected List<LifeMovementFragment> parseMovement(LittleEndianAccessor lea) {
        List<LifeMovementFragment> res = new ArrayList<LifeMovementFragment>();
        //System.out.println("\r\n移动包："+lea.toString());
        int numCommands = lea.readByte();//循环次数
        //System.out.println("循环次数："+numCommands);
        for (int i = 0; i < numCommands; i++) {
            int command = lea.readByte();//移动类型
            //System.out.println("移动类型："+command);
            switch (command) {
                case 0: // 正常移动
                case 15: //093 轻羽鞋
                case 37: //龙神
                case 38: //龙神
                {
                    int xpos = lea.readShort();//x坐标
                    int ypos = lea.readShort();//y坐标
                    int xwobble = lea.readShort();//x摇动
                    int ywobble = lea.readShort();//y摇动
                    int unk = lea.readShort();
                    lea.readInt();
                    int newstate = lea.readByte();
                    int duration = lea.readShort();//持续时间
                    AbsoluteLifeMovement alm = new AbsoluteLifeMovement(command, new Point(xpos, ypos), duration, newstate);
                    alm.setUnk(unk);
                    alm.setPixelsPerSecond(new Point(xwobble, ywobble));
                    res.add(alm);
                    break;
                }
                case 1:
                case 2: //怪物移动[小金人]
                case 6: // fj
                case 19: //龙卷风 092 - 18
                {
                    int xmod = lea.readShort();
                    int ymod = lea.readShort();
                    int newstate = lea.readByte();
                    int duration = lea.readShort();
                    RelativeLifeMovement rlm = new RelativeLifeMovement(command, new Point(xmod, ymod), duration, newstate);
                    res.add(rlm);
                    break;
                }
                case 5: //093变更
                case 4: // tele... -.-
                case 7: // assaulter 攻击者?
                case 8: // 暗杀
                case 9: //093变更
                case 14: { //瞬移
                    int xpos = lea.readShort();
                    int ypos = lea.readShort();
                    int xwobble = lea.readShort();
                    int ywobble = lea.readShort();
                    int newstate = lea.readByte();
                    TeleportMovement tm = new TeleportMovement(command, new Point(xpos, ypos), newstate);
                    tm.setPixelsPerSecond(new Point(xwobble, ywobble));
                    res.add(tm);
                    break;
                }
                case 10: //bigBang - 9 当脱下或者穿上装备之后并且未进行移动时 丢物品的坐标不对 就是这个原因
                {
                    res.add(new ChangeEquipSpecialAwesome(command, lea.readByte()));
                    break;
                }
                case 3: //093变更
                case 11: // 椅子
                case 12: //原来是下跳 现在不知道是什么
                {
                    int xpos = lea.readShort();
                    int ypos = lea.readShort();
                    int unk = lea.readShort();
                    int newstate = lea.readByte();
                    int duration = lea.readShort();
                    ChairMovement cm = new ChairMovement(command, new Point(xpos, ypos), duration, newstate);
                    cm.setUnk(unk);
                    res.add(cm);
                    break;
                }
                case 13: //下跳
                { 
                    int xpos = lea.readShort();
                    int ypos = lea.readShort();
                    int xwobble = lea.readShort();
                    int ywobble = lea.readShort();
                    int unk = lea.readShort();
                    int fh = lea.readShort();
                    lea.readInt();
                    int newstate = lea.readByte();
                    int duration = lea.readShort();
                    JumpDownMovement jdm = new JumpDownMovement(command, new Point(xpos, ypos), duration, newstate);
                    jdm.setUnk(unk);
                    jdm.setPixelsPerSecond(new Point(xwobble, ywobble));
                    jdm.setFH(fh);
                    res.add(jdm);
                    break;
                }
                case 16: //093
                case 20: 
                case 21: 
                case 22: 
                case 23:
                case 24: 
                case 25: //093
                case 26: 
                case 27:
                case 28: {
                    int unk = lea.readShort();
                    int newstate = lea.readByte();
                    ArasMovement acm = new ArasMovement(command, new Point(0, 0), unk, newstate);
                    res.add(acm);
                    break;
                }
                default: {
                    log.warn("未知的移动类型：{}", command);
                    log.warn("未知的移动封包: {}", lea.toString());
                    WriteToFile re = new WriteToFile("D:\\ErrorPacket\\MoveError1.txt");
                    re.WriteFile("unknowMoveType：["+command+"]");
                    //re.WriteFile("\r\n"+lea.toString());
                    re.CloseFile();
                    return null;
                }
            }
        }
        if (numCommands != res.size()) {
            System.out.println("解析错误的移动包："+lea.toString());
            log.warn("循环次数[{}]和实际上获取的循环次数[{}]不符", numCommands, res.size());
            WriteToFile re = new WriteToFile("D:\\ErrorPacket\\MoveError2.txt");
            re.WriteFile("moveSize：["+numCommands+"]\r\nnowSize：["+res.size()+"]");
            //re.WriteFile("\r\n"+lea.toString());
            re.CloseFile();
        }
        return res;
    }

    protected void updatePosition(List<LifeMovementFragment> movement, AnimatedMapleMapObject target, int yoffset) {
        for (LifeMovementFragment move : movement) {
            if (move instanceof LifeMovement) {
                if (move instanceof AbsoluteLifeMovement) {
                    Point position = ((LifeMovement) move).getPosition();
                    position.y += yoffset;
                    target.setPosition(position);
                }
                target.setStance(((LifeMovement) move).getNewstate());
            }
        }
    }
}